/**
 *
 */
package com.wfe.generics.grm;

import java.io.Serializable;
import java.util.Date;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;

import com.se.grm.client.mapping.GrmRequest;
import com.se.grm.client.mapping.GrmRequestMessege;
import com.se.grm.client.mapping.GrmRequestStatusHistory;
import com.se.grm.client.mapping.GrmRequestStaus;
import com.se.grm.client.mapping.GrmUser;
import com.util.EngineUtil;
import com.wfe.db.SessionUtil;
import com.wfe.db.WorkFlowEngineQueryUtil;
import com.wfe.mapping.client.Request;
import com.wfe.mapping.client.WfProjectTaskStatus;

/**
 * @author kareem_yehya
 * 
 */
public abstract class GRMRequestHandlerImpl extends Request implements Serializable
{

	/**
	 *
	 */
	private static final long serialVersionUID = -7770945409570029853L;

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Runnable#run()
	 */

	/**
	 * @author kareem_yehya
	 * @since 31 October 2010 <br>
	 *        This method should be overrideen and supposed to be abstract
	 * 
	 * */

	public abstract boolean execute();

	/**
	 * Should be called when request Sucess
	 * 
	 * @author kareem_yehya
	 * @since 31 October 2010
	 * 
	 * */

	public void requestSuccess()
	{

		try
		{
			Request request = getRequestById(this.getRecid());
			request.setWfProjectTaskStatus(getWfProjectTaskStatusByID(1l));
			request.setProcessingDate(new Date());
			updateRequest(request);
			GrmRequest grmRequest = getGRMRequestById(request.getRequestId());
			changeRequestStatusOnGRM(grmRequest, 14l);
		}catch(Exception e)
		{
			e.printStackTrace();
		}
	}

	/**
	 * Should be called when request Failed
	 * 
	 * @author kareem_yehya
	 * @since 31 October 2010
	 * 
	 * */
	public void requestFailed()
	{
		try
		{
			Request request = getRequestById(this.getRecid());
			request.setWfProjectTaskStatus(getWfProjectTaskStatusByID(2l));
			request.setProcessingDate(new Date());
			updateRequest(request);

			GrmRequest grmRequest = getGRMRequestById(request.getRequestId());

			changeRequestStatusOnGRM(grmRequest, 15l);
		}catch(Exception e)
		{
			e.printStackTrace();
		}

	}

	public Request getRequestById(long i)
	{

		Session session = null;
		try
		{
			session = SessionUtil.getSession();
			Criteria criteria = session.createCriteria(Request.class);
			criteria.add(Restrictions.eq("recid", i));
			return (Request) criteria.uniqueResult();
		}catch(Exception e)
		{
			e.printStackTrace();
			return null;
		}finally
		{

			EngineUtil.closeSession(session);

		}

	}

	public GrmRequest getGRMRequestById(long i)
	{

		Session session2 = null;
		try
		{
			session2 = com.se.grm.db.SessionUtil.getSession();
			Criteria criteria = session2.createCriteria(GrmRequest.class);
			criteria.add(Restrictions.eq("id", i));
			return (GrmRequest) criteria.uniqueResult();
		}catch(Exception e)
		{
			e.printStackTrace();
			return null;
		}finally
		{
			if(session2 != null)
				session2.close();

		}

	}

	public void updateRequest(Request request)
	{

		Session session = null;
		try
		{
			session = SessionUtil.getSession();
			session.update(request);
			session.beginTransaction().commit();

		}catch(Exception e)
		{
			e.printStackTrace();
		}finally
		{

			EngineUtil.closeSession(session);

		}

	}

	public WfProjectTaskStatus getWfProjectTaskStatusByID(long i)
	{

		Session session = null;
		try
		{
			session = SessionUtil.getSession();
			Criteria criteria = session.createCriteria(WfProjectTaskStatus.class);
			criteria.add(Restrictions.eq("recid", i));
			return (WfProjectTaskStatus) criteria.uniqueResult();
		}catch(Exception e)
		{
			e.printStackTrace();
			return null;
		}finally
		{
			EngineUtil.closeSession(session);
		}
	}

	public void addMessageToSpecificRequest(GrmRequest grmRequest, String message) throws Exception
	{
		Session s = null;
		try
		{
			s = com.se.grm.db.SessionUtil.getSession();
			s.saveOrUpdate(new GrmRequestMessege(System.nanoTime(), getGrmUser(999999999l), grmRequest, message, new Date()));
		}catch(Exception e)
		{
			e.printStackTrace();
			throw new Exception(e.getCause());
		}finally
		{
			if(s != null)
				s.close();
		}
	}

	/**
	 * 
	 * @author kareem_yehya
	 * 
	 * @since 23 October 2010
	 * 
	 * 
	 * */

	private boolean changeRequestStatusOnGRM(GrmRequest grmRequest, long statusID)
	{

		// 1- change it is status to WFE_Inprogress by adding record to history
		GrmRequestStatusHistory grmRequestStatusHistory = null;
		GrmRequestStaus grmRequestStaus = null;
		GrmUser grmUser = null;
		Session session2 = null;
		try
		{
			grmRequestStaus = getGrmRequestStaus(statusID);
			grmUser = getGrmUser(999999999l);// / WFE User
			grmRequestStatusHistory = new GrmRequestStatusHistory(WorkFlowEngineQueryUtil.getRandomID(), grmUser, grmRequestStaus, grmRequest, new Date());
			session2 = com.se.grm.db.SessionUtil.getSession();
			session2.save(grmRequestStatusHistory);
			System.out.println("New Request History record has been Added RequestID = " + grmRequest.getId());
			return true;
		}catch(Exception e)
		{
			e.printStackTrace();
			return false;
		}finally
		{
			if(session2 != null)
				session2.close();

		}

	}

	/**
	 * @author kareem_yehya
	 * @since 24 October 2010
	 * */

	private GrmRequestStaus getGrmRequestStaus(long status_ID)
	{
		Session session2 = null;
		GrmRequestStaus grmRequestStaus = null;
		try
		{
			session2 = com.se.grm.db.SessionUtil.getSession();
			Criteria criteria = session2.createCriteria(GrmRequestStaus.class);
			criteria.add(Restrictions.eq("id", status_ID));
			grmRequestStaus = (GrmRequestStaus) criteria.uniqueResult();
			return grmRequestStaus;
		}catch(Exception e)
		{
			e.printStackTrace();
			return null;
		}finally
		{
			if(session2 != null)
				session2.close();
		}
	}

	private GrmUser getGrmUser(long ID)
	{
		Session session2 = null;
		GrmUser grmUser = null;
		try
		{
			session2 = com.se.grm.db.SessionUtil.getSession();
			Criteria criteria = session2.createCriteria(GrmUser.class);
			criteria.add(Restrictions.eq("id", ID));
			grmUser = (GrmUser) criteria.uniqueResult();
			return grmUser;
		}catch(Exception e)
		{
			e.printStackTrace();
			return null;
		}finally
		{
			if(session2 != null)
				session2.close();
		}
	}

}
